<?php
/**
 *      [迷你云] (C)2009-2012 南京恒为网络科技.
 *   软件仅供研究与学习使用，如需商用，请访问www.miniyun.cn获得授权
 * 
 */
?>
<?php





class Logger {
	private static $_classes = array(
	);

	
	private $additive = true;
	
	
	private $fqcn = 'Logger';

	
	private $level;
	
	
	private $name;
	
	
	private $parent;
	
	
	private $appenders = array();

	
	private static $hierarchy;
	
	
	private static $configurationClass = 'LoggerConfiguratorBasic';
	
	
	private static $configurationFile;
	
	
	private static $initialized = false;
	
	
	public function __construct($name) {
		$this->name = $name;
	}
	
	
	public function getName() {
		return $this->name;
	} 

	
	public function getParent() {
		return $this->parent;
	}
	
	
	public static function getHierarchy() {
		if(!isset(self::$hierarchy)) {
			self::$hierarchy = new LoggerHierarchy(new LoggerRoot());
		}
		return self::$hierarchy;
	}
	
	
	
	public function trace($message, $caller = null) {
		$this->log(LoggerLevel::getLevelTrace(), $message, $caller);
	} 		
	
	
	public function debug($message, $caller = null) {
		$this->log(LoggerLevel::getLevelDebug(), $message, $caller);
	} 


	
	public function info($message, $caller = null) {
		$this->log(LoggerLevel::getLevelInfo(), $message, $caller);
	}

	
	public function warn($message, $caller = null) {
		$this->log(LoggerLevel::getLevelWarn(), $message, $caller);
	}
	
	
	public function error($message, $caller = null) {
		$this->log(LoggerLevel::getLevelError(), $message, $caller);
	}
	
	
	public function fatal($message, $caller = null) {
		$this->log(LoggerLevel::getLevelFatal(), $message, $caller);
	}
	
	
	public function forcedLog($fqcn, $caller, $level, $message) {
		$throwable = ($caller !== null && $caller instanceof Exception) ? $caller : null;
		
		$this->callAppenders(new LoggerLoggingEvent($fqcn, $this, $level, $message, null, $throwable));
	} 
	
	
	
	public function isDebugEnabled() {
		return $this->isEnabledFor(LoggerLevel::getLevelDebug());
	}		

	
	public function isEnabledFor($level) {
		return (bool)($level->isGreaterOrEqual($this->getEffectiveLevel()));
	} 

	
	public function isInfoEnabled() {
		return $this->isEnabledFor(LoggerLevel::getLevelInfo());
	} 

	
	public function log($priority, $message, $caller = null) {
		if($this->isEnabledFor($priority)) {
			$this->forcedLog($this->fqcn, $caller, $priority, $message);
		}
	}
	
	
	public function assertLog($assertion = true, $msg = '') {
		if($assertion == false) {
			$this->error($msg);
		}
	}
	
	 
	
	
	public static function getLogger($name) {
		if(!self::isInitialized()) {
			self::initialize();
		}
		return self::getHierarchy()->getLogger($name);
	}
	
		   
	public static function getRootLogger() {
		if(!self::isInitialized()) {
			self::initialize();
		}
		return self::getHierarchy()->getRootLogger();	  
	}
	
	
	
	
	public function addAppender($appender) {
		$appenderName = $appender->getName();
		$this->appenders[$appenderName] = $appender;
	}
	
	
	public function removeAllAppenders() {
		$appenderNames = array_keys($this->appenders);
		$enumAppenders = count($appenderNames);
		for($i = 0; $i < $enumAppenders; $i++) {
			$this->removeAppender($appenderNames[$i]); 
		}
	} 
			
	
	public function removeAppender($appender) {
		if($appender instanceof LoggerAppender) {
			$appender->close();
			unset($this->appenders[$appender->getName()]);
		} else if (is_string($appender) and isset($this->appenders[$appender])) {
			$this->appenders[$appender]->close();
			unset($this->appenders[$appender]);
		}
	} 
			
	
	public function callAppenders($event) {
		foreach($this->appenders as $appender) {
			$appender->doAppend($event);
		}
		
		if($this->parent != null and $this->getAdditivity()) {
			$this->parent->callAppenders($event);
		}
	}
	
	
	public function getAllAppenders() {
		return array_values($this->appenders);
	}
	
	
	public function getAppender($name) {
		return $this->appenders[$name];
	}
	
	
	public function getAdditivity() {
		return $this->additive;
	}
 
	
	public function getEffectiveLevel() {
		for($c = $this; $c != null; $c = $c->parent) {
			if($c->getLevel() !== null) {
				return $c->getLevel();
			}
		}
		return null;
	}
  
	
	public function getLevel() {
		return $this->level;
	}
	
	
	public function setLevel($level) {
		$this->level = $level;
	}
	
	
	public static function clear() {
		return self::getHierarchy()->clear();	 
	}
	
	
	public static function resetConfiguration() {
		$result = self::getHierarchy()->resetConfiguration();
		self::$initialized = false;
		self::$configurationClass = 'LoggerConfiguratorBasic';
		self::$configurationFile = null;
		return $result;	 
	}

	
	public static function shutdown() {
		return self::getHierarchy()->shutdown();	   
	}
	
	
	public static function exists($name) {
		return self::getHierarchy()->exists($name);
	}
	
	
	public static function getCurrentLoggers() {
		return self::getHierarchy()->getCurrentLoggers();
	}
	
	
	public function isAttached(LoggerAppender $appender) {
		return isset($this->appenders[$appender->getName()]);
	} 
		   
	
	public function setAdditivity($additive) {
		$this->additive = (bool)$additive;
	}

	
	public function setParent(Logger $logger) {
		$this->parent = $logger;
	} 
	
	
	public static function configure($configurationFile = null, $configurationClass = null ) {
		if($configurationClass === null && $configurationFile === null) {
			self::$configurationClass = 'LoggerConfiguratorBasic';
			return;
		}
									 	
		if($configurationClass !== null) {
			self::$configurationFile = $configurationFile;
			self::$configurationClass = $configurationClass;
			return;
		}
		
		if (strtolower(substr( $configurationFile, -4 )) == '.xml') {
			self::$configurationFile = $configurationFile;
			self::$configurationClass = 'LoggerConfiguratorXml';
		} else {
			self::$configurationFile = $configurationFile;
			self::$configurationClass = 'LoggerConfiguratorIni';
		}
	}
	
	
	public static function getConfigurationClass() {
		return self::$configurationClass;
	}
	
	
	public static function getConfigurationFile() {
		return self::$configurationFile;
	}
	
	
	private static function isInitialized() {
		return self::$initialized;
	}
	
	
	public static function initialize() {
		self::$initialized = true;
		$instance = LoggerReflectionUtils::createObject(self::$configurationClass);
		$result = $instance->configure(self::getHierarchy(), self::$configurationFile);
		return $result;
	}
}
